<template>
  <div class="file-card">
    <div class="upload-content" style="border: 0" v-if="fileListData.length < maxLength">
      <el-upload
        ref="upload"
        action=""
        :file-list="fileListData"
        :show-file-list="false"
        multiple
        :limit="maxLength"
        :before-upload="beforeUpload"
        :on-exceed="oneExceed"
        :http-request="customUpload"
        :on-error="onError"
      >
        <div class="upload-card">
          <div class="upload-btn">
            <svg-icon style="font-size: 20px; margin-right: 5px" iconClass="upload-icon" />
            上传附件
          </div>
          <div class="format-limit">支持上传rar/zip/doc/docx/xls/xlsx/pdf/jpg/png，单个文件不超过100M</div>
        </div>
      </el-upload>
    </div>
    <div class="file-list">
      <div class="file-item" v-for="(item, index) in fileListData" :key="item.fileId">
        <div class="file-info">
          <el-image
            v-if="['jpg', 'png'].includes(getSuffix(item.fileName ?? item.name))"
            class="file-info__img"
            :src="item.fileUrl"
            fit="cover"
          ></el-image>
          <svg-icon v-else style="font-size: 32px; margin-right: 5px" iconClass="default-file" />
          <span>{{ item.fileName }}</span>
        </div>
        <svg-icon @click="handleRemove(index)" style="font-size: 24px; margin-right: 5px; cursor: pointer" iconClass="del-file" />
      </div>
    </div>
  </div>
</template>

<script setup>
import { computed, getCurrentInstance, ref, watch } from "vue";
import { fileReadRole, setACL, signatureUrl } from "@/utils/aliOssUpload";
import useMultipartOssStore from "@/store/modules/multipartOss";
import defaultConfig from "@/settings";
import { getVideoTime} from "./utils";
import {generateId} from "@/utils/index"

const props = defineProps({
  fileList: {
    type: Array,
    default: () => []
  },
  itemSize: {
    type: String,
    default: "84px"
  },
  maxSize: {
    type: Number,
    default: 10
  },
  maxLength: {
    type: Number,
    default: 9
  },
  disabled: Boolean,
  multiple: Boolean,
  isLimitDuration: Boolean,
  limitDuration: {
    type: Number,
    default: 60
  }
});
const emits = defineEmits(["uploadSuccess", "uploadRemove"]);
const { proxy } = getCurrentInstance();
const multipartOssStore = useMultipartOssStore();

const fileListData = ref([]);
watch(
  () => props.fileList,
  newVal => {
    props.fileList.forEach(item => {
      item.fileUrl && (multipartOssStore.loadingArr[item.fileId] = 100);
    });
    fileListData.value = [...newVal];
  },
  { immediate: true, deep: true }
);

/**
 * TODO:限制文件类型，还可以在优化，目前文件类型必须传入组件
 */

const beforeUpload = async file => {
  console.log(file);
  const suffix = getSuffix(file.name);
  const maxSize = file.size / 1024 / 1024 < 10;
  const isInFileType = ["rar", "zip", "doc", "docx", "xls", "xlsx", "pdf", "jpg", "png"].includes(suffix);
  if (!isInFileType) {
    proxy.$modal.msgError(`只能上传指定类型的文件!`);
    return false;
  }
  if (!maxSize) {
    proxy.$modal.msgError(`单个文件大小不能超过${props.maxSize}M!`);
    return false;
  }
  if (props.isLimitDuration) {
    const duration = await getVideoTime(file);
    if (duration > props.limitDuration) {
      proxy.$modal.msgError(`单个文件大小不能超过${props.limitDuration}秒!`);
      return false;
    }
  }
  return true;
};
const oneExceed = () => {
  proxy.$modal.msgError(`最多上传${props.maxLength}个文件`);
  return false;
};
const getSuffix = fileName => {
  return fileName.slice(fileName.lastIndexOf(".") + 1);
};
const getFileName = fileName => {
  return fileName.slice(0, fileName.lastIndexOf("."));
};
const fileToBlob = file => {
  return {
    fileId: file.uid,
    uid: file.uid,
    name: file.name,
    size: file.size,
    type: file.type,
    suffix: file.suffix,
    fileUrl: URL.createObjectURL(file)
  };
};
const customUpload = async option => {
  fileListData.value.push(fileToBlob(option.file));
  multipartOssStore.loadingArr[option.file.uid] = 0;
  // const nowTime = dayjs().format("YYYY-MM-DD HH:mm:ss");
  let file = option.file,
    fileName = option.file.name;
  fileName = `${getFileName(fileName)}-${generateId()}.${getSuffix(fileName)}`;
  file = new File([file], fileName, { type: file.type });
  let objName = `${defaultConfig.fileFolder}/${file.name}`;
  multipartOssStore
    .submit(objName, file, option.file.uid)
    .then(async res => {
      await setACL(objName, fileReadRole.publicRead);
      const fileUrl = await signatureUrl(objName);
      const fileObj = {
        fileId: option.file.uid,
        fileName: file.name,
        fileUrl: fileUrl ? `${fileUrl}`.split("?")[0] : ""
      };
      // res.fileUrl = fileUrl ? `${fileUrl}`.split("?")[0] : "";
      // res.fileId = option.file.uid;
      // res.fileName = file.name;
      // emits("uploadSuccess", res);
      emits("uploadSuccess", fileObj);
    })
    .catch(err => {
      console.log(err);
      fileListData.value.pop();
      alert(JSON.stringify(err));
    });
};
const onError = () => {};
const handleRemove = index => {
  emits("uploadRemove", index);
};
</script>

<style lang="scss" scoped>
.file-card {
  background: #f6f8fa;
  .upload-card {
    text-align: center;
    padding: 15px;
    border-bottom: 1px solid #e1e6ed;
    .upload-btn {
      color: #007dff;
      font-size: 14px;
      display: flex;
      align-items: center;
      justify-content: center;
    }
    .format-limit {
      font-size: 12px;
      color: #86909c;
    }
  }
  .file-list {
    padding: 18px 12px;
    .file-item {
      display: flex;
      align-items: center;
      justify-content: space-between;
      margin-bottom: 10px;
      &:last-child {
        margin-bottom: 0;
      }
      .file-info {
        display: flex;
        align-items: center;
        &__img {
          width: 32px;
          height: 32px;
          border-radius: 4px;
          margin-right: 5px;
        }
        span {
          width: 200px;
          white-space: nowrap;
          text-overflow: ellipsis;
          display: inline-block;
          overflow: hidden;
          font-size: 12px;
          color: #3d3d3d;
        }
      }
      &__del {
      }
    }
  }
}
</style>
